package com.ebocy.hammer.core.message;

import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

import org.apache.mina.core.buffer.IoBuffer;

import com.ebocy.hammer.core.constants.GameMessageCode;

/**
 * 2012-4-10@author yangshaobo
 */
public abstract class AbstractS2CMessage implements IMessage {
	private IoBuffer data = IoBuffer.allocate(8, true).setAutoExpand(true);
	private static final CharsetEncoder utf8Encoder = Charset.forName("UTF-8").newEncoder();

	/** 在写list的时候 长度一定要用short */
	protected abstract void writeMessage();

	protected AbstractS2CMessage() {
		writeShort(this.getMessageCode());
	}

	@Override
	public abstract short getMessageCode();

	// protected void writeLong(long value) {
	// this.data.putLong(value);
	// }

	protected void writeByte(byte value) {
		this.data.put(value);
	}

	protected void writeShort(short value) {
		this.data.putShort(value);
	}

	protected void writeInt(int value) {
		this.data.putInt(value);
	}

	protected void writeFloat(float value) {
		this.data.putFloat(value);
	}

	protected void writeString(String value) {
		try {
			data.putShort((short) value.getBytes().length);
			data.putString(value, utf8Encoder);
		} catch (CharacterCodingException e) {
			e.printStackTrace();
		}
	}

	protected void writeListByte(Collection<Byte> list) {
		data.putShort((short) list.size());
		for (Byte value : list)
			data.put(value);
	}

	protected void writeListInt(Collection<Integer> list) {
		data.putShort((short) list.size());
		for (Integer value : list)
			data.putInt(value);
	}

	protected void writeListLong(Collection<Long> list) {
		data.putShort((short) list.size());
		for (Long value : list)
			data.putLong(value);
	}

	protected void writeListShort(Collection<Short> list) {
		data.putShort((short) list.size());
		for (Short value : list)
			data.putShort(value);
	}

	protected void writeListFloat(Collection<Float> list) {
		data.putShort((short) list.size());
		for (Float value : list)
			data.putFloat(value);
	}

	protected void writeMap(Map<Long, Long> map) {
		try {
			data.putShort((short) map.size());
			Set<Long> set = map.keySet();
			for (Long value : set) {
				String temp = String.valueOf(value) + "," + map.get(value);
				data.putShort((short) temp.getBytes().length);
				data.putString(temp, utf8Encoder);
			}
		} catch (CharacterCodingException e) {
			e.printStackTrace();
		}
	}

	protected void writeListString(Collection<String> list) {
		try {
			data.putShort((short) list.size());
			for (String value : list) {
				data.putShort((short) value.getBytes().length);
				data.putString(value, utf8Encoder);
			}
		} catch (CharacterCodingException e) {
			e.printStackTrace();
		}
	}

	protected void writeListObject(Collection<AbstractS2CMessage> objectList) {
		data.putShort((short) objectList.size());
		for (AbstractS2CMessage object : objectList) {
			data.put(object.getDataNoLength());
		}
	}

	public IoBuffer getData() {
		writeMessage();
		data.flip();
		IoBuffer buffer = IoBuffer.allocate(data.limit() + 4);
		buffer.putInt(data.limit() + 4);
		buffer.put(data);// 消息内容
		buffer.flip();
		return buffer;
	}

	public IoBuffer getDataNoLength() {
		writeMessage();
		data.flip();
		IoBuffer buffer = IoBuffer.allocate(data.limit());
		buffer.put(data);// 消息内容
		buffer.flip();
		return buffer;
	}

}
